package com.sinodata.bsm.cicp.collector.weblogic9;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.Query;
import javax.management.QueryExp;
import javax.management.remote.JMXConnector;

import org.apache.log4j.Logger;

import com.sinodata.bsm.cicp.collector.Collector;
import com.sinodata.bsm.cicp.exception.CollectorException;
import com.sinodata.bsm.cicp.util.JmxUtil;
import com.sinodata.bsm.common.vo.ResPropertyValue;

/**
 * 
 * <p>
 * Description: 
 * </p>
 *
 * @author liulibo
 * @version 1.0

 * <p>
 * History: 
 *
 * Date                     Author         Version     Description
 * ---------------------------------------------------------------------------------
 * 2012-12-26 AM 10:07:17   liulibo        1.0         To create
 * </p>
 *
 * @since 
 * @see
 */
public class EjbTransactionCollector extends Collector {

    private static final Logger logger = Logger.getLogger(EjbTransactionCollector.class);

    private final HashMap ejb = new HashMap();
    private final Set set = new HashSet();
    private long lastTime = -1;

    @Override
    public List<ResPropertyValue> collect(String ip) throws CollectorException {
        List<ResPropertyValue> values = new ArrayList<ResPropertyValue>();

        String[] propMetas = getPropMeta();
        ResPropertyValue propertyValueX = new ResPropertyValue();
        ResPropertyValue.PropValue[] propValues = new ResPropertyValue.PropValue[propMetas.length];

        //        String ejbName = this.getParamMap().get("名字").trim();
        //        String serversName = this.getParamMap().get("服务器名字").trim();
        //        String port = this.getParamMap().get("port").trim();
        String ejbName = this.getParamMap().get("Name").trim();
        String serversName = this.getParamMap().get("ServersName").trim();
        String port = this.getParamMap().get("port").trim();

        String key = serversName + ":" + ip;
        QueryExp destFilter = Query.match(Query.attr("Type"), Query.value("EJBTransactionRuntime"));
        Object attrValues[] = null;
        JMXConnector connector = null;
        MBeanServerConnection connection = null;
        try {
            connector = JmxUtil.getConnection(ip, Integer.valueOf(port));
            connection = connector.getMBeanServerConnection();
            long currentTimeMillis = System.currentTimeMillis();
            if (set.isEmpty() || currentTimeMillis > lastTime + 60 * 60 * 1000) {
                set.clear();
                Set test = connection.queryNames(new ObjectName("com.bea:*"), destFilter);
                set.addAll(test);
                lastTime = currentTimeMillis;
            }
            Iterator it = set.iterator();
            while (it.hasNext()) {
                ObjectName objName = (ObjectName) it.next();
                String serverRuntime = objName.getKeyProperty("ServerRuntime");
                String applicationRuntime = objName.getKeyProperty("ApplicationRuntime");
                propValues[0] = ResPropertyValue.createPropValue(applicationRuntime, propMetas[0]);
                String attributeNames[] = new String[] { "Name", "TransactionsCommittedTotalCount", "TransactionsRolledBackTotalCount", "TransactionsTimedOutTotalCount" };
                attrValues = JmxUtil.getAttribute(connection, objName, attributeNames);
                if ((serverRuntime.equals(serversName)) && (attrValues[0].toString().equals(ejbName))) {
                    for (int i = 1; i < attrValues.length; i++) {
                        propValues[i] = ResPropertyValue.createPropValue(attrValues[i].toString(), propMetas[i]);
                    }
                }
            }
        } catch (Exception e) {
            logger.error("failed to collect by EjbTransactionCollector", e);
            throw new CollectorException(e);
        } finally {
            JmxUtil.closeConnector(connector);
        }
        if (ejb.get(key) != null) {
            String temp = String.valueOf(ejb.get(key));
            String[] valueTime = temp.split("[:]");//
            String resultString = null;
            if (Long.parseLong(valueTime[0]) - Long.parseLong(attrValues[1].toString()) != 0) {
                resultString = String.valueOf((Long.parseLong(valueTime[0]) - Long.parseLong(attrValues[3].toString())) * 60 / (Long.parseLong(valueTime[0]) - Long.parseLong(attrValues[1].toString())));
            }
            if ((attrValues[4].toString() == null) || (Long.parseLong(attrValues[4].toString()) < 0)) {
                resultString = "0";
            }
            propValues[4] = ResPropertyValue.createPropValue(resultString, propMetas[4]);
        }
        ejb.remove(key);
        ejb.put(key, attrValues[3].toString() + ":" + attrValues[1].toString());
        propertyValueX.setValues(propValues);
        values.add(propertyValueX);
        return values;
    }

    @Override
    public String[] getParamMeta() {
        return new String[] { "Name", "ServersName", "port" };
    }

    @Override
    public String[] getPropMeta() {
        //     return new String[] { "ApplicationName", "TransactionsCommittedTotalCount", "TransactionsRolledBackTotalCount", "TransactionsTimedOutTotalCount", "TransactionsTimedOutRatio" };
        return new String[] { "$1", "$2", "$3", "$4", "$5" };
    }

}
